const Comment = require('../models/comment.model');
const Video = require('../models/video.model');
const Post = require('../models/post.model');
const User = require('../models/user.model');
const { validationResult } = require('express-validator');
const { toAbsoluteUrl } = require('../utils/urlUtils'); // 确保导入

// 添加评论 (视频或帖子)
async function addComment(req, res) {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
        return res.status(400).json({ errors: errors.array() });
    }

    try {
        const { text, parentId, targetType, targetId } = req.body;
        const userId = req.user._id;

        let targetModel;
        let updateField;

        if (targetType === 'video') {
            targetModel = Video;
            updateField = 'comments';
        } else if (targetType === 'post') {
            targetModel = Post;
            updateField = 'comments';
        } else {
            return res.status(400).json({ error: '无效的目标类型' });
        }

        const target = await targetModel.findById(targetId);
        if (!target) {
            return res.status(404).json({ error: `${targetType === 'video' ? '视频' : '帖子'}不存在` });
        }
        // 对于帖子，可能需要检查是否是草稿
        if (targetType === 'post' && target.isDraft) {
            return res.status(403).json({ error: '不能评论草稿' });
        }

        const commentData = {
            text,
            user: userId,
            targetId,
            targetType,
            status: 'active',
            replies: []
        };

        if (parentId) {
            const parentComment = await Comment.findById(parentId);
            if (!parentComment) {
                return res.status(404).json({ error: '父评论不存在' });
            }
            // 确保父评论和子评论的目标一致
            if (!parentComment.targetId.equals(targetId) || parentComment.targetType !== targetType) {
                return res.status(400).json({ error: '父评论与目标不匹配' });
            }
            commentData.parentId = parentId;
            // 初始化回复数组
            if (!parentComment.replies) {
                parentComment.replies = [];
            }
        }

        const comment = new Comment(commentData);
        await comment.save();

        // 将评论 ID 添加到视频或帖子的评论数组中
        target[updateField].push(comment._id);
        await target.save();

        // 如果是回复，也更新父评论的 replies 数组
        if (parentId) {
            await Comment.findByIdAndUpdate(parentId, { $push: { replies: comment._id } });
        }

        // Populate user information before sending response
        const populatedComment = await Comment.findById(comment._id).populate('user', 'username avatar');

        res.status(201).json({ message: '评论添加成功', comment: populatedComment });

    } catch (error) {
        console.error('添加评论失败:', error);
        res.status(500).json({ error: '添加评论失败' });
    }
}

// 辅助函数：递归填充评论的用户信息和头像 URL
async function populateCommentTree(comment) {
  if (!comment) return null;

  // 填充当前评论的用户信息
  if (comment.user && typeof comment.user === 'object' && comment.user.avatar) {
    comment.user.avatar = toAbsoluteUrl(comment.user.avatar);
  } else if (comment.user && typeof comment.user === 'string') {
    // 如果 user 只是 ID，需要重新 populate
    await comment.populate('user', 'username avatar');
    if (comment.user && comment.user.avatar) {
      comment.user.avatar = toAbsoluteUrl(comment.user.avatar);
    }
  }

  // 递归填充回复
  if (comment.replies && comment.replies.length > 0) {
    const populatedReplies = [];
    for (const reply of comment.replies) {
      // 确保回复被完全填充
      let populatedReply = reply;
      if (typeof reply === 'string' || !reply.user) { // 如果是 ID 或未填充 user
        populatedReply = await Comment.findById(reply)
          .populate('user', 'username avatar')
          .populate({ // 递归填充回复的回复
            path: 'replies',
            populate: { path: 'user', select: 'username avatar' }
            // 可以继续嵌套 populate 以支持更深层级，但这会增加查询复杂度
            // 考虑限制层级或在前端按需加载更深层回复
          });
      }
      const processedReply = await populateCommentTree(populatedReply);
      if (processedReply) {
        populatedReplies.push(processedReply);
      }
    }
    comment.replies = populatedReplies;
  }

  return comment;
}

// 获取评论列表 (视频或帖子)
async function getComments(req, res) {
    try {
        const { targetType, targetId } = req.params;
        const page = parseInt(req.query.page) || 1;
        const limit = parseInt(req.query.limit) || 10;
        const skip = (page - 1) * limit;
        const sortBy = req.query.sort || 'latest'; // latest, popular

        let query = { targetId, targetType, parentId: null }; // 只获取顶层评论
        // let query = { targetId, targetType }; // 获取所有评论

        let sortOption = { createdAt: -1 }; // 默认按最新排序
        if (sortBy === 'popular') {
            sortOption = { likes: -1, createdAt: -1 }; // 按点赞数排序
        }

     
        const totalCommentsCountQuery = { targetId, targetType }; 
        const totalComments = await Comment.countDocuments(totalCommentsCountQuery);
        
        // 获取当前页的顶层评论
        const topLevelComments = await Comment.find(query)
            .sort(sortOption)
            .skip(skip)
            .limit(limit)
            .populate('user', 'username avatar')
            .populate({
                path: 'replies',
                match: { status: 'active' }, // 恢复状态过滤，只显示 active 的回复
                populate: {
                    path: 'user',
                    select: 'username avatar'
                },
                options: { sort: { createdAt: 1 } }
            });

        // 直接处理查询结果中的头像 URL
        const processedComments = topLevelComments.map(comment => {
            const commentObj = comment.toObject(); // 获取普通 JS 对象
            // 处理顶层评论用户头像
            if (commentObj.user && commentObj.user.avatar) {
                try {
                    commentObj.user.avatar = toAbsoluteUrl(commentObj.user.avatar);
                } catch (e) {
                    console.error(`Error processing avatar URL for top-level comment ${commentObj._id}:`, e);
                    commentObj.user.avatar = null;
                }
            }
            // 处理回复用户头像
            if (commentObj.replies && commentObj.replies.length > 0) {
                commentObj.replies = commentObj.replies.map(reply => {
                    if (reply.user && reply.user.avatar) {
                         try {
                            reply.user.avatar = toAbsoluteUrl(reply.user.avatar);
                        } catch (e) {
                            console.error(`Error processing avatar URL for reply ${reply._id}:`, e);
                            reply.user.avatar = null;
                        }
                    }
                    return reply;
                });
            }
            return commentObj;
        });

        res.json({
            comments: processedComments,
            currentPage: page,
            totalPages: Math.ceil(totalComments / limit),
            totalComments
        });

    } catch (error) {
        console.error('获取评论列表失败:', error);
        res.status(500).json({ error: '获取评论列表失败' });
    }
}

// 更新评论
async function updateComment(req, res) {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
        return res.status(400).json({ errors: errors.array() });
    }

    try {
        const commentId = req.params.id;
        const userId = req.user._id;
        const { text } = req.body;

        const comment = await Comment.findById(commentId);

        if (!comment) {
            return res.status(404).json({ error: '评论不存在' });
        }

        // 检查权限
        if (!comment.user.equals(userId)) {
            return res.status(403).json({ error: '没有权限修改该评论' });
        }

        comment.text = text;
        comment.isEdited = true; // 标记为已编辑
        await comment.save();

        // Populate user information before sending response
        const populatedComment = await Comment.findById(comment._id).populate('user', 'username avatar');

        res.json({ message: '评论更新成功', comment: populatedComment });

    } catch (error) {
        console.error('更新评论失败:', error);
        res.status(500).json({ error: '更新评论失败' });
    }
}

// 删除评论
async function deleteComment(req, res) {
    try {
        const commentId = req.params.id;
        const userId = req.user._id;

        const comment = await Comment.findById(commentId);

        if (!comment) {
            return res.status(404).json({ error: '评论不存在' });
        }

        // 检查权限 (评论作者、目标内容作者或管理员)
        let targetModel;
        if (comment.targetType === 'video') targetModel = Video;
        else if (comment.targetType === 'post') targetModel = Post;
        else return res.status(500).json({ error: '无效的评论目标类型' });

        const target = await targetModel.findById(comment.targetId);
        const isTargetOwner = target && target.user.equals(userId);
        const isAdmin = req.user.role === 'admin';
        const isCommentOwner = comment.user.equals(userId);

        if (!isCommentOwner && !isTargetOwner && !isAdmin) {
            return res.status(403).json({ error: '没有权限删除该评论' });
        }

        // --- 递归软删除子评论 ---
        async function recursiveSoftDelete(commentIdToDelete) {
            const c = await Comment.findById(commentIdToDelete);
            if (!c) return;
            if (c.replies && c.replies.length > 0) {
                for (const replyId of c.replies) {
                    await recursiveSoftDelete(replyId);
                }
            }
            await c.softDelete(); // 使用软删除方法
        }

        await recursiveSoftDelete(commentId);
        // --- 递归软删除结束 ---

        res.json({ message: '评论删除成功' });

    } catch (error) {
        console.error('删除评论失败:', error);
        res.status(500).json({ error: '删除评论失败' });
    }
}

// 点赞/取消点赞评论
async function likeComment(req, res) {
    try {
        const commentId = req.params.id;
        const userId = req.user._id;

        const comment = await Comment.findById(commentId);
        const user = await User.findById(userId);

        if (!comment) {
            return res.status(404).json({ error: '评论不存在' });
        }
        if (comment.isDeleted) {
             return res.status(400).json({ error: '不能对已删除的评论进行操作' });
        }

        const userIndexInCommentLikes = comment.likes.indexOf(userId);

        let liked = false;
        if (userIndexInCommentLikes === -1) {
            // 点赞
            comment.likes.push(userId);
            liked = true;
        } else {
            // 取消点赞
            comment.likes.splice(userIndexInCommentLikes, 1);
        }
        await comment.save();

        res.json({ liked, likesCount: comment.likes.length });

    } catch (error) {
        console.error('点赞/取消点赞评论失败:', error);
        res.status(500).json({ error: '操作失败' });
    }
}

// 获取用户对评论的交互状态 (是否点赞)
async function getCommentInteractionStatus(req, res) {
    try {
        const commentId = req.params.id;
        const userId = req.user?._id;

        const comment = await Comment.findById(commentId).select('likes');

        if (!comment) {
            return res.status(404).json({ error: '评论不存在' });
        }

        let liked = false;
        if (userId && comment.likes.includes(userId)) {
            liked = true;
        }

        res.json({ liked, likesCount: comment.likes.length });

    } catch (error) {
        console.error('获取评论交互状态失败:', error);
        res.status(500).json({ error: '获取状态失败' });
    }
}

// 管理员获取所有评论列表
async function getAllCommentsForAdmin(req, res) {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
        return res.status(400).json({ errors: errors.array() });
    }

    // 检查管理员权限
    if (!req.user || req.user.role !== 'admin') {
        return res.status(403).json({ error: '没有管理员权限' });
    }

    try {
        const page = parseInt(req.query.page) || 1;
        const limit = parseInt(req.query.limit) || 10;
        const skip = (page - 1) * limit;
        const searchQuery = req.query.search || '';
        const typeFilter = req.query.type;
        const statusFilter = req.query.status;

        let query = {};

        // 构建搜索条件
        if (searchQuery) {
            try {
                const searchRegex = new RegExp(searchQuery, 'i');
                // 搜索评论内容或用户名
                console.log(`[Admin Comments] Searching users with username matching: ${searchQuery}`);
                const users = await User.find({ username: searchRegex }).select('_id');
                const userIds = users.map(u => u._id);
                console.log(`[Admin Comments] Found ${userIds.length} users matching search.`);
                query.$or = [
                    { text: searchRegex },
                    { user: { $in: userIds } }
                ];
            } catch (userSearchError) {
                console.error('[Admin Comments] Error searching users:', userSearchError);
                const searchRegex = new RegExp(searchQuery, 'i');
                query.text = searchRegex; 
            }
        }

        // 构建过滤条件
        if (typeFilter) {
            query.targetType = typeFilter;
        }
        if (statusFilter) {
            query.status = statusFilter;
        }

        const totalComments = await Comment.countDocuments(query);
        const comments = await Comment.find(query)
            .sort({ createdAt: -1 }) 
            .skip(skip)
            .limit(limit)
            .populate('user', 'username avatar'); 

        // 分别获取视频和帖子评论的目标ID
        const videoCommentIds = [];
        const postCommentIds = [];
        comments.forEach(comment => {
            if (comment.targetType === 'video' && comment.targetId) {
                videoCommentIds.push(comment.targetId);
            } else if (comment.targetType === 'post' && comment.targetId) {
                postCommentIds.push(comment.targetId);
            }
        });

        // 批量查询视频和帖子
        const [videos, posts] = await Promise.all([
            videoCommentIds.length > 0 ? Video.find({ _id: { $in: videoCommentIds } }).select('title') : [],
            postCommentIds.length > 0 ? Post.find({ _id: { $in: postCommentIds } }).select('title') : []
        ]);

        // 创建查找映射
        const videoMap = new Map(videos.map(v => [v._id.toString(), v]));
        const postMap = new Map(posts.map(p => [p._id.toString(), p]));

        // 进一步处理 targetId 和 user avatar
        const populatedComments = comments.map(comment => {
            const commentObj = comment.toObject();
            
            // 根据目标类型设置标题
            if (comment.targetType === 'video' && videoMap.has(comment.targetId.toString())) {
                commentObj.targetTitle = videoMap.get(comment.targetId.toString()).title;
            } else if (comment.targetType === 'post' && postMap.has(comment.targetId.toString())) {
                commentObj.targetTitle = postMap.get(comment.targetId.toString()).title;
            } else {
                commentObj.targetTitle = '[来源未知或已删除]';
            }
           
            // 安全处理 user avatar URL
            if (commentObj.user && commentObj.user.avatar) {
                try {
                    commentObj.user.avatar = toAbsoluteUrl(commentObj.user.avatar);
                } catch (urlError) {
                    console.error(`Error processing avatar URL for comment ${commentObj._id}, user ${commentObj.user._id}:`, urlError);
                    commentObj.user.avatar = null; 
                }
            }

            return commentObj;
        });

        res.json({
            comments: populatedComments,
            currentPage: page,
            totalPages: Math.ceil(totalComments / limit),
            totalComments
        });

    } catch (error) {
        console.error('管理员获取评论列表失败:', error);
        res.status(500).json({ error: '获取评论列表失败' });
    }
}

// 管理员批量更新评论状态
async function batchUpdateCommentStatus(req, res) {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
        return res.status(400).json({ errors: errors.array() });
    }

    try {
        const { ids, status } = req.body;

        const result = await Comment.updateMany(
            { _id: { $in: ids } },
            { $set: { status: status } }
        );

        if (result.matchedCount === 0) {
            return res.status(404).json({ error: '未找到任何匹配的评论' });
        }

        res.json({ message: `成功更新 ${result.modifiedCount} 条评论的状态为 ${status}` });

    } catch (error) {
        console.error('批量更新评论状态失败:', error);
        res.status(500).json({ error: '批量更新评论状态失败' });
    }
}

// 管理员批量删除评论
async function batchDeleteComments(req, res) {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
        return res.status(400).json({ errors: errors.array() });
    }

    try {
        const { ids } = req.body;


        // 查找所有待删除的评论及其子评论 ID
        const commentsToDelete = await Comment.find({ _id: { $in: ids } });
        let allIdsToDelete = [...ids];

        async function findAllChildren(commentId) {
            const children = await Comment.find({ parentId: commentId });
            for (const child of children) {
                if (!allIdsToDelete.includes(child._id.toString())) {
                    allIdsToDelete.push(child._id.toString());
                    await findAllChildren(child._id);
                }
            }
        }

        for (const id of ids) {
            await findAllChildren(id);
        }

        // 执行删除
        const deleteResult = await Comment.deleteMany({ _id: { $in: allIdsToDelete } });


        if (deleteResult.deletedCount === 0) {
            return res.status(404).json({ error: '未找到任何匹配的评论进行删除' });
        }

        res.json({ message: `成功删除了 ${deleteResult.deletedCount} 条评论（包含子评论）` });

    } catch (error) {
        console.error('批量删除评论失败:', error);
        res.status(500).json({ error: '批量删除评论失败' });
    }
}


module.exports = {
    addComment,
    getComments, 
    updateComment,
    deleteComment,
    likeComment,
    getCommentInteractionStatus,
    getAllCommentsForAdmin,
    batchUpdateCommentStatus,
    batchDeleteComments
};